package db

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"sync"
	"telemple_web/app/core/config"
)

// 缓存数据库链接实例
var dbInstance = make(map[string]*gorm.DB)

// 防止链接实例 并发时候相互影响
var dbLock sync.RWMutex

func Load(configDB config.DBEleConfig, configLog config.DBLog, key string) *gorm.DB {
	dbLock.RLock()
	db, ok := dbInstance[key]
	if ok {
		dbLock.RUnlock()
		return db
	}
	dbLock.RUnlock()

	//业务流程有两个
	//创建的环节 需要并发锁，到这里来上面已经执行了
	dbLock.Lock()
	defer dbLock.Unlock()

	if _, exist := dbInstance[key]; exist {
		return dbInstance[key]
	}
	dbInstance[key] = getDbInstance(configDB, configLog)
	return dbInstance[key]
}

func getDbInstance(configDB config.DBEleConfig, configLog config.DBLog) *gorm.DB {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local&timeout=%s&writeTimeout=%s&readTimeout=%s",
		configDB.Username,
		configDB.Password,
		configDB.Host,
		configDB.Port,
		configDB.Database,
		configDB.Charset,
		configDB.Timeout,
		configDB.WriteTimeout,
		configDB.ReadTimeout)
	//db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	//db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
	//	Logger: logger.Default.LogMode(logger.Info),
	//})

	logConfig := gorm.Config{}
	if configLog.Enabled {
		logConfig.Logger = logger.Default.LogMode(logger.Info)
	}
	db, err := gorm.Open(mysql.Open(dsn), &logConfig)
	if err != nil {
		panic(fmt.Sprintf("failed to connect database: %v", err))
	}

	// 数据库连接池配置
	sqlDB, err := db.DB()
	if err != nil {
		panic(fmt.Sprintf("failed to connect database: %v", err))
	}
	sqlDB.SetMaxIdleConns(configDB.MaxIdleConnections)
	sqlDB.SetMaxOpenConns(configDB.MaxOpenConnections)

	return db
}
